/*
 * @Author: wangming
 * @Date: 2020-09-03 16:33:37
 * @LastEditors: wangming
 * @LastEditTime: 2022-06-01 15:26:01
 * @Description: file content
 */
import myMixin from '@/pageComponents/myMixin';
import vmMixin from "@/pageComponents/vmMixin";
import { cloneDeep } from "lodash";
import { postHmhttprequestdefinitionExecute } from '@/apis/paas/HmHttpRequestDefinitionController.js'
import { getHmdictionaryOptions } from '@/apis/paas/HmDictionaryController.js'
import { dataToList } from "@/utils/util";
import { getVueComponent } from "@/utils/common.js";
export default {
  mixins: [myMixin, vmMixin],
  vmEvents: {
    async reload(keyword) {
      await this.getExecuteApi(keyword);
    },
    async setData(tableData) {
      this.optionsList = []
      await this.$nextTick()
      this.optionsList = this.changeMapOptions(tableData).map(i => Object.assign({}, i, { value: (i.value + "").match(/[\w\u4e00-\u9fa5-]+/g) + '' }))
    },
    getData() {
      return cloneDeep(this.optionsList);
    },
    getSelectData() {
      return this.optionsList.filter((i) => {
        if (this.config.__config.multiple) {
          return this.datas.indexOf(i.value) > -1;
        } else {
          return i.value == this.datas;
        }
      });
    },
  },
  data() {
    return {
      remote: true,
      datas: '',
      optionsList: [],
      keyword: undefined,
      maxWidth:0
    };
  },
  computed: {
    isCustom() {
      const { dataCustomLoad, dataCustomLoadFn } = this.config.__config;
      return dataCustomLoad && dataCustomLoadFn
    },
    dataLoadFunction() {
      const { dataCustomLoadFn } = this.config.__config;
      return getVueComponent(dataCustomLoadFn);
    },
  },
  methods: {
    getDropFun(data) {
      try {
        let fun = decodeURIComponent(this.config.__config.parseDataJsx).match(
          /function parseData[\s\S]+/
        )
        return new Function("return " + fun)()(data)
      } catch (error) {
        return data
      }
    },
    async beforeChangeHook(value) {
      if (!!this.config.__config.beforeChange) {
        let res = await getVueComponent(this.config.__config.beforeChange)(
          this.vmEvents?.context,
          value
        );
        if (res === false) {
          return Promise.reject();
        }
      } else {
        return Promise.resolve();
      }
    },
    async def(value = '') {
      if (value === null) value = '';
      let values = (value + "").match(/[\w\u4e00-\u9fa5-]+/g) || []
      if (this.config.__config.multiple) {
        this.datas = values
      } else {
        this.datas = values[0] || '';
      }
      if (!!value && !!this.optionsList.length && this.config.__config.relationType === 'BUSINESS' && !this.isCustom) {
        await this.$nextTick()
        //当id不存在前30条的时候需要扩大查询
        let hasOptions = values.filter(id => this.optionsList.every(i => i.value != id))
        if (hasOptions.length > 0) {
          let data = await this.loadApis(0, hasOptions.join(','))
          this.optionsList.push(...this.changeMapOptions(data))
        }
      }
      this.changeChildForm()
    },
    async getDictionary() {
      this.remote = false
      //字典
      let data = await getHmdictionaryOptions({ type: this.config.__config.valueTeam }, { useCache: true })
      data = data.map(({ optionValue, optionName, localism }) => ({ label: this.$at(localism) || optionName, id: optionValue }))
      this.TransformList(data)
    },
    async getExecuteApi(keyword) {
      this.keyword = keyword
      if (this.isCustom) {
        let data = await this.getCustomData(30, this.value)
        this.TransformList(data)
      } else if (this.config.__config.relationType === 'BUSINESS') {
        let data = await this.loadApis(30, this.value)
        this.TransformList(data)
      } else if (this.config.__config.relationType === 'DICTIONARY'){
        this.getDictionary()
      }
    },
    async loadApis(limit = 30, value) {
      return await postHmhttprequestdefinitionExecute({
        key: 'selectList',
        modelKey: this.config.__config.modelKey,
        values: {
          limit,
          keyword: this.keyword,
          fieldCode: this.config.modelName,
          _RELATION_TYPE_: 'BUSINESS',
          _IDS_: value?.match(/[\w\u4e00-\u9fa5-]+/g)?.join(',') || ''
        },
      }, { useCache: true });
    },
    async getCustomData(limit = 30, value) {
      let options = await this.dataLoadFunction(
        this.vmEvents?.context,
        this.vmEvents?.exports,
        {
          limit,
          keyword: this.keyword,
          fieldCode: this.config.modelName,
          _RELATION_TYPE_: this.config.__config.relationType,
          _IDS_: value?.match(/[\w\u4e00-\u9fa5-]+/g)?.join(',') || ''
        }
      );
      return dataToList(options)
    },
    TransformList(data) {
      this.optionsList = this.changeMapOptions(this.getDropFun(data));
    },
    changeMapOptions(data) {
      try {
        return data.map(item => ({ ...item, value: item.value === undefined ? item.id + '' : item.value + '' }))
      } catch (error) {
        console.error(error)
      }
    },
    changeChildForm() {
      if (!!this.descForm) {
        let desc = ''
        try {
          if (this.config.__config.multiple) {
            desc =
              this.optionsList
                .filter((i) => {
                  return this.datas.indexOf(i.value) > -1;
                })
                .map((i) => i.label) + "";
          } else {
            desc = this.optionsList.find((i) => this.datas === i.value)?.label
          }
        } catch (error) { }
        this.descForm[this.config.modelName] = desc;
      }
    },
  },
  async created() {
    if (this.config.__config.cancelLoad || this.isEdit) return
    await this.getExecuteApi();
    this.changeChildForm()
  },
  watch: {
    value: {
      handler: 'def',
      immediate: true
    }
  },
  render(h) {
    const { placeholder, width, multiple, relationType } = this.config.__config;
    if (this.isEdit) {
      return (<el-input
        style={{
          width: width + '%'
        }}
        placeholder={placeholder}
      />)
    }
    if (this.viewInfo) {
      const viewDatas = []
      if (multiple) {
        this.datas.forEach(item => {
          this.optionsList.forEach(option => {
            if (option.value === item) {
              viewDatas.push(option)
            }
          })
        })
        const tagList = viewDatas.map(item => {
          return h('el-tag', {
            style: { marginRight: '5px' },
            attrs: {
              type: 'info'
            }
          }, item.label);
        })
        return (
          h('div', {
            style: { display: 'inline-block', whiteSpace: 'break-spaces', width: width + '%' }
          },
            tagList
          )
        );
      } else {
        if (!this.datas) return
        [this.datas].forEach(item => {
          this.optionsList.forEach(option => {
            if (option.value === item) {
              viewDatas.push(option)
            }
          })
        })
        return (
          <div style={{ display: 'inline-block', whiteSpace: 'break-spaces', width: width + '%' }}>
            {viewDatas[0]?.label}
          </div>
        );
      }
    }
    const itemtran = ({ label, value }) =>
      h('el-option', {
        attrs: {
          label,
          value,
          title:label
        },
        style: { 'max-width':this.maxWidth === 0 ? '100%' : this.maxWidth + 'px'},
      });
    const optionList = this.optionsList.map(itemtran);
    if (optionList.length > 29 && relationType === 'BUSINESS') {
      optionList.push(h('div', {
        attrs: {
          class: "g9 f12 pl20 pr20"
        }
      }, '只显示前30条结果，请完善搜索关键字'))
    }
    return h(
      'el-select',
      {
        on: {
          change: async (v) => {
            try {
              // 执行值变化前钩子
              await this.beforeChangeHook(v)
              if (this.config.__config.multiple) {
                const str = v.map(i => `[${i}]`).join('')
                this.$emit('input', str);
                this.runEventName('change', { values: str });
              } else {
                if (this.config.__config.codeType !== "RELATION_REFERENCE" && v !== '') {
                  v = `[${v}]`
                }
                this.$emit('input', v);
                this.runEventName('change', { values: v });
              }
            } catch (error) {
              console.log(error)
            }
          },
          'visible-change': v => {
            if (!v && !!this.keyword?.replace(' ', '')) {
              this.getExecuteApi();
            }
          },
          focus: v => {
            const node = v.srcElement || v.target
            this.maxWidth = node.clientWidth
          }
        },
        style: { width: width + '%' },
        attrs: {
          clearable: true,
          value: this.datas,
          multiple,
          placeholder,
          disabled: this.disabled,
          remote: this.remote,
          filterable: true,
          'reserve-keyword': true,
          remoteMethod: this.remote ? (e) => {
            this.getExecuteApi(e);
          } : undefined
        }
      },
      optionList
    );

  }
};
